# CSRF Protection

  • Introduction

    Cross-site request forgeries are a type of malicious exploit whereby unauthorized commands are performed on behalf of an authenticated user. Thankfully, Rails makes it easy to protect your application from cross-site request forgery (opens new window)(CSRF) attacks.

  • An Explanation of the vulnerability

    In case you're not familiar with cross-site request forgeries, let's discuss an example of how this vulnerability can be exploited. Imagine your application has a **/user/email**route that accepts a **POST**request to change the authenticated user's email address. Most likely, this route expects an **email**input field to contain the email address the user would like to begin using.

    Without CSRF protection, a malicious website could create an HTML form that points to your application's **/user/email**route and submits the malicious user's own email address:

    <form action="https://your-application.com/user/email" method="POST">
        <input type="email" value="malicious-email@example.com">
    </form>
     
    <script>
        document.forms[0].submit();
    </script>
    
    1
    2
    3
    4
    5
    6
    7

    If the malicious website automatically submits the form when the page is loaded, the malicious user only needs to lure an unsuspecting user of your application to visit their website and their email address will be changed in your application.

    To prevent this vulnerability, we need to inspect every incoming POSTPUTPATCH, or DELETE request for a secret session value that the malicious application is unable to access.

  • Preventing CSRF Requests

    Remember, any HTML forms pointing to POSTPUTPATCH, or DELETE routes that are defined in the web routes file should include a CSRF token field. Otherwise, the request will be rejected.

    As a Rails developer, you basically get CSRF protection for free. It starts with this single line in application_controller.rb, which enables CSRF protection:

    protect_from_forgery with: :exception
    
    1

    Next, there's this single line in application.html.erb: